package cn.gov.pbc.gd.credit.core.service.work.impl;

import java.time.DayOfWeek;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.liu.jbase.PageListVo;
import com.liu.jbase.ResultVo;
import com.liu.jbase.service.impl.BaseServiceImpl;
import com.liu.tools.PrimaryUtil;

import cn.gov.pbc.gd.credit.api.work.IWorkApi;
import cn.gov.pbc.gd.credit.core.service.work.IWorkService;
import cn.gov.pbc.gd.credit.vo.work.ResWorkVo;
import cn.gov.pbc.gd.credit.vo.work.WorkVo;

@Service
public class WorkServiceImpl extends BaseServiceImpl<ResWorkVo, WorkVo, IWorkApi> implements IWorkService {

	@Autowired
	private IWorkApi workApi;

	@Override
	public ResultVo<PageListVo<ResWorkVo>> page(WorkVo record, PageListVo<ResWorkVo> page, HttpServletRequest request) {

		// 得到jsp页面传回的年，月，每页显示数量
		int year = Integer.parseInt(request.getParameter("year") == null ? "2017" : request.getParameter("year"));

		int month = Integer.parseInt(request.getParameter("month") == null ? "1" : request.getParameter("month"));

		int pageSize = Integer
				.parseInt(request.getParameter("pageSize") == null ? "42" : request.getParameter("pageSize"));
		page.setPageSize(pageSize);

		// 得到当月1号前，第一个星期六的日期。
		Date beginDay = getFirstDayInMonth(year, month);
		record.setBeginDay(beginDay);

		//查询beginDay在数据库中是否存在
		WorkVo workVo=new WorkVo();
		
		workVo.setDay(beginDay);
		
		if(!workVoInData(workVo)){//如果数据库中不存在，该日期，则向数据库填充一年的日期。
			
			insertDayByYear(beginDay);//向数据库中填充当年，一整年的日期
			
		}
		
		//查询的起始日期到42天之后的日期(即当前页最后一个日期)
		Date endDay = localDateTimeToDate(dateToLocalDateTime(beginDay).plusDays(42));
		
		workVo.setDay(endDay);
		
		if(!workVoInData(workVo)){//如果数据库中不存在，该日期，则向数据库填充一年的日期。
			
			int flag = insertDayByYear(endDay);//向数据库中填充当年，一整年的日期
			
			if(flag <= 0){
				LocalDateTime ldt = LocalDateTime.now();
				Date nowDay = getFirstDayInMonth(ldt.getYear(),ldt.getMonthValue());
				record.setBeginDay(nowDay);
			}
			
		}
		
		// 查询42天的日期，显示到页面
		ResultVo<PageListVo<ResWorkVo>> result = super.page(record, page, request);

		return result;
	}

	@Override
	public ResultVo<List<ResWorkVo>> list(WorkVo record, HttpServletRequest request) {

		ResultVo<List<ResWorkVo>> result = super.list(record, request);

		return result;
	}

	/**
	 * 得到当前日期，当前月2号的之前的第一个星期六的日期
	 * @param year 年
	 * @param month 月
	 * @return 得到当前日期，当前月2号的之前的第一个星期六的日期
	 */
	private  Date getFirstDayInMonth(int year, int month) {

		ZoneId zone = ZoneId.systemDefault();// 创建系统默认时区

		LocalDateTime fistDayForMonth = LocalDateTime.of(year, month, 1, 0, 0);// 创建当前年月1号的日期

		int dayOfWeek = fistDayForMonth.getDayOfWeek().getValue();// 当前年月1号，是星期几（1-7）

		LocalDateTime fistSundayDate = fistDayForMonth;// 创建待新的时间类，记录星期天的日期

		if (dayOfWeek != 7) {

			// 如果1号不是星期天，则用当月1号日期，减去对应天数，得到1号前第一个星期天的日期。
			fistSundayDate = fistDayForMonth.minusDays(dayOfWeek);

		}
		// 得到周六的日期
		LocalDateTime fistSatdayDate = fistSundayDate.minusDays(1);

		Instant instant2 = fistSatdayDate.atZone(zone).toInstant();

		return Date.from(instant2);// LocalDateTime-->Date
	}

	// 根据当前日期，向数据库一次性填充一年的日期，返回是否添加成功，0添加失败，非0添加成功
	private int insertDayByYear(Date date) {

		int flag = 0;// 判断是否添加成功

		LocalDateTime localDateTime = dateToLocalDateTime(date);

		LocalDateTime startTime = LocalDateTime.of(localDateTime.getYear(), 1, 1, 8, 0);// 起始日期，当年的1月1日

		LocalDateTime endTime = LocalDateTime.of(localDateTime.getYear() + 1, 1, 1, 8, 0);// 结束日期，次年的1月1日
		
		List<WorkVo> listWorkVo = new ArrayList<>();

		while (startTime.isBefore(endTime)) {// 当 起始日期 小于 结束日期，则进入循环，插入数据。

			WorkVo workVo = getWorkVoByDate(startTime);// 根据日期，创建WorkVo类，用于插入数据库

			listWorkVo.add(workVo);// 加入到集合中

			startTime = startTime.plusDays(1);// 将起始日期加一天。

		}
		
		flag=workApi.insertList(listWorkVo);

		return flag;
	}

	private boolean workVoInData(WorkVo workVo) {

		boolean flag = false;
		
		List<ResWorkVo> list = workApi.list(workVo);//数据库中list查询，根据workVo中的day查
		
		if (list.size() > 0) {//判断list长度，大于零表示数据库中有
			flag = true;
		}
		
		return flag;
	}

	// 根据传入的日期，创建一个当前日期的WorkVo类
	private  WorkVo getWorkVoByDate(LocalDateTime localDateTime) {
		
		WorkVo workVo = new WorkVo();

		// 设置id
		String id = PrimaryUtil.primaryId("W");
		workVo.setId(id);

		// 设置日期
		workVo.setDay(localDateTimeToDate(localDateTime));
		
		//设置创建时间
		workVo.setCreateTime(new Date());
		
		// 设置工作日 0 or 1
		int isWork = 0;
		
		DayOfWeek dayOfWeek = localDateTime.getDayOfWeek();
		
		int week = dayOfWeek.getValue();
		
		if (week >= 1 && week <= 5) {
			isWork = 1;
		}
		
		workVo.setIsWork(isWork); // 设置工作日
		
		workVo.setWeek(week); // 设置星期

		return workVo;
	}

	// 将LocalDateTime转换为Date
	private  Date localDateTimeToDate(LocalDateTime localDateTime) {

		ZoneId zone = ZoneId.systemDefault();

		Instant instant = localDateTime.atZone(zone).toInstant();

		Date date = Date.from(instant);

		return date;
	}

	// 将Date转换为LocalDateTime
	private  LocalDateTime dateToLocalDateTime(Date date) {

		ZoneId zone = ZoneId.systemDefault();

		Instant instant = date.toInstant();

		LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, zone);

		return localDateTime;
	}

}
